package cn.edu.zzuli.nothinglink.service.impl;

import cn.edu.zzuli.nothinglink.entity.R;
import cn.edu.zzuli.nothinglink.entity.Work;
import cn.edu.zzuli.nothinglink.entity.WorkPostpone;
import cn.edu.zzuli.nothinglink.entity.WorkPutPostponeRecord;
import cn.edu.zzuli.nothinglink.mapper.WorkMapper;
import cn.edu.zzuli.nothinglink.mapper.WorkPutPostponeRecordMapper;
import cn.edu.zzuli.nothinglink.service.WorkPostponeService;
import cn.edu.zzuli.nothinglink.service.WorkPutPostponeRecordService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author suzyyy
 * @since 2021-04-08
 */
@Service
public class WorkPutPostponeRecordServiceImpl extends ServiceImpl<WorkPutPostponeRecordMapper, WorkPutPostponeRecord> implements WorkPutPostponeRecordService {

    @Autowired
    WorkPostponeService workPostponeService;

    @Resource
    WorkMapper workMapper;

    @Override
    @Transactional
    public R putWorkPostpone(Integer workId, Integer stuId) {
        WorkPutPostponeRecord workPutPostponeRecord = new WorkPutPostponeRecord();
        workPutPostponeRecord.setStuId(stuId).setWorkId(workId);

        //这里为了并发考虑，先这样写着。
        synchronized (WorkPutPostponeRecordServiceImpl.class) {

            WorkPostpone postpone = workPostponeService.getOne(
                new LambdaQueryWrapper<WorkPostpone>().eq(WorkPostpone::getWorkId, workId)
            );

            if (postpone == null) {
                //那么新建
                postpone = new WorkPostpone();
                postpone.setWorkId(workId)
                        .setAgreeNumbers(1)
                        .setIsReply(0)
                        .setTeaId(postpone.getTeaId());

                Work work = workMapper.selectById(workId);
                if (work == null) return R.error().add("info", "作业不存在。");
                //保存
                postpone.setTeaId(work.getWorkTeaId());
                workPostponeService.save(postpone);
            }else {
                //0为未审批，1为审批
                if (postpone.getIsReply().equals(1)) return R.error().add("info", "此作业老师已经更改日期。");
                //同意人数+1
                workPostponeService.updateById(postpone.setAgreeNumbers(postpone.getAgreeNumbers() + 1));
            }
            WorkPutPostponeRecord stuPutPostponeRecord = this.getOne(new LambdaQueryWrapper<WorkPutPostponeRecord>()
                    .eq(WorkPutPostponeRecord::getWpId, postpone.getWpId())
                    .eq(WorkPutPostponeRecord::getStuId, stuId)
            );

            if (stuPutPostponeRecord == null) {

                workPutPostponeRecord.setWpId(postpone.getWpId());
                //新增一条记录
                this.save(workPutPostponeRecord);
                return R.success().add("info", "请求延期成功");
            }

            return R.success().add("info", "你已经请求延期过了，请勿重新请求");

        }


    }

    @Override
    public R getRecords(Integer stuId) {
        //获取该学生全部的请求推迟记录
        List<WorkPutPostponeRecord> putPostponeRecords = this.list(
                new LambdaQueryWrapper<WorkPutPostponeRecord>()
                        .eq(WorkPutPostponeRecord::getStuId, stuId)
                        .orderByDesc(WorkPutPostponeRecord::getCreateTime)
        );

        //获取对应的推迟的记录
        Set<Integer> wpIds = putPostponeRecords.stream().map(WorkPutPostponeRecord::getWpId).collect(Collectors.toSet());

        Map<Integer, WorkPostpone> postponeMap = workPostponeService.listIgnoreDeleteBatchIds(wpIds).stream().collect(Collectors.toMap(k -> k.getWpId(), v -> v));

        //获取推迟的作业信息，以此来获取课程的名字
        Collection<WorkPostpone> WorkPostpones = postponeMap.values();
        Set<Integer> workIds = WorkPostpones.stream()
                .map(p -> p.getWorkId()).collect(Collectors.toSet());
        Map<Integer, Work> workMap = workMapper.selectBatchIds(workIds).stream().collect(Collectors.toMap(k -> k.getWorkId(), v -> v));

        putPostponeRecords.forEach(ppr -> {
            WorkPostpone postpone = postponeMap.get(ppr.getWpId());
            ppr.setPostponeTime(postpone.getPostponeTime());
            ppr.setWorkName(workMap.get(postpone.getWorkId()).getWorkName());
            ppr.setCourseName(workMap.get(postpone.getWorkId()).getCourseName());
        });

        return R.success().add("records", putPostponeRecords);
    }
}
